<template>
	<!-- 实名认证信息卡片 -->
	<el-card class="box-card">
		<!-- 卡片头部 -->
		<template #header>
			<div class="card-header">
				<h1>实名信息</h1>
			</div>
		</template>
		<!-- 卡片身体 -->
		<div class="tip">
			<el-icon>
				<Warning />
			</el-icon>
			<el-text type="info">完成实名认证后才能添加就诊人，正常进行挂号，为了不影响后续步骤，建议提前实名认证。</el-text>
		</div>
		<!-- 认证成功的结构 -->
		<el-descriptions v-if="memberInfo?.authStatus" :column="1" border>
			<el-descriptions-item label-align="center" width="40">
				<template #label>
					<span>用户姓名</span>
				</template>
				{{ memberInfo.name }}
			</el-descriptions-item>
			<el-descriptions-item label-align="center">
				<template #label>
					<span>证件类型</span>
				</template>
				{{ memberInfo.certificatesType == 10 ? "身份证" : "户口本" }}
			</el-descriptions-item>
			<el-descriptions-item label-align="center">
				<template #label>
					<span>证件号码</span>
				</template>
				{{ memberInfo.certificatesNo }}
			</el-descriptions-item>
		</el-descriptions>
		<!-- 未认证的结构 -->
		<el-form ref="form" :rules="rules" :model="formData" v-else class="form" label-width="80">
			<el-form-item prop="name" label="用户姓名">
				<el-input placeholder="请输入用户姓名" v-model="formData.name" />
			</el-form-item>
			<el-form-item prop="certificatesType" label="证件类型">
				<el-select style="width: 100%;" placeholder="请选择证件类型" v-model="formData.certificatesType">
					<!-- 需要为下拉菜单项绑定value，作为选中后的值 -->
					<el-option v-for="(type, index) in certificationTypeArr" :key="index" :label="type.name"
						:value="type.value"></el-option>
				</el-select>
			</el-form-item>
			<el-form-item prop="certificatesNo" label="证件号码">
				<el-input placeholder="请输入证件号码" v-model="formData.certificatesNo" />
			</el-form-item>
			<el-form-item prop="certificatesUrl" label="上传证件">
				<!-- 照片墙 -->
				<!-- 
					action	upload 组件向服务器提交图片的路径
					limit	照片墙约束图片的个数
					on-exceed	超出约束数量的钩子
					on-success	文件上传成功时的钩子
					on-preview	点击文件列表中已上传的文件时的钩子
					on-remove	文件列表移除文件时的钩子
				 -->
				<el-upload ref="upload" :on-remove="removeHandle" :on-preview="previewHandle" :on-success="successHandle"
					:on-exceed="exceedHandle" :limit="1" list-type="picture-card"
					action="/api/oss/file/fileUpload?fileHost=userAuah">
					<img style="width: 100%;" src="@/assets/images/auth_example.png" alt="图片示例">
				</el-upload>

				<el-dialog v-model="dialogVisible">
					<img style="width: 100%;" :src="formData.certificatesUrl" alt="Preview Image" />
				</el-dialog>
			</el-form-item>
			<el-form-item>
				<el-button @click="submitUserAuah" type="primary">提交</el-button>
				<el-button @click="reset">重写</el-button>
			</el-form-item>
		</el-form>
	</el-card>
</template>

<script setup lang="ts">
defineOptions({
	name: "Certification"
})
import { reqCertificationType, reqMemberInfo, reqUserAuah } from '@/api/user';
import { CertificationTypeArr, CertificationTypeResponse, MemberInfoData, UserAuahData } from '@/api/user/type';
//引入小图标
import { Warning } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { onMounted, ref } from 'vue';


//存储用户信息
let memberInfo = ref<any>()
// 存储证件类型
let certificationTypeArr = ref<CertificationTypeArr>()
// 存储表单信息
let formData = ref<UserAuahData>({
	"certificatesNo": "",
	"certificatesType": "",
	"certificatesUrl": "",
	"name": ""
})
// 是否显示图片预览框
let dialogVisible = ref<boolean>(false)
// 储存元素节点
let upload = ref()
// 表单校验规则对象
const rules = {
	// 用户名的校验规则
	name: [
		/*
		required: true，表示当前字段务必进行校验
		validator:vilidatorName，表示当前字段的自定义校验规则函数
		 */
		{
			required: true,
			validator: vilidatorName,
		}
	],
	certificatesType: [
		{
			required: true,
			validator: vilidatorType
		}
	],
	certificatesNo: [
		{
			required: true,
			validator: vilidatorNo,
		}
	],
	certificatesUrl: [
		{
			required: true,
			validator: vilidatorUrl,
		}
	]
}
// 储存元素节点
let form = ref()

/*---自定义校验规则---
rule：当前校验字段的校验对象
value：当前校验字段的值
callback：放行函数（通过校验条件后执行）
 */
// 姓名的自定义校验
function vilidatorName(_rule: any, value: any, callback: any) {
	// 定义一个正则表达式
	const reg = /^[\u00B7\u3007\u3400-\u9FFF\uE000-\uF8FF\uF900-\uFAFF\u{20000}-\u{2FFFF}\u{30000}-\u{3FFFF}]+$/u
	// 如果符合正则则放行
	if (reg.test(value)) {
		callback();
	} else {
		callback(new Error("请输入正确的姓名"))
	}
}
// 证件类型的自定义校验
function vilidatorType(_rule: any, value: any, callback: any) {
	if (value === "10" || value === "20") {
		callback()
	} else {
		callback(new Error("请选择正确的证件类型"))
	}
}
// 证件号码的自定义校验
function vilidatorNo(_rule: any, value: any, callback: any) {
	const reg = /^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
	if (reg.test(value)) {
		callback();
	} else {
		callback(new Error("请输入正确的证件号码"))
	}
}
// 证件图片地址的自定义校验
function vilidatorUrl(_rule: any, value: any, callback: any) {
	const reg = /^https?:\/\/(.+\/)+.+(\.(gif|png|jpg|jpeg|webp|svg|psd|bmp|tif))$/i
	if (reg.test(value)) {
		callback();
	} else {
		callback(new Error("请上传证件照"))
	}
}


//获取会员信息
async function getUserInfo() {
	let result: MemberInfoData = await reqMemberInfo();
	if (result.code === 200) {
		memberInfo.value = result.data
	}
}
// 获取证件类型
async function getCertificationType() {
	let result: CertificationTypeResponse = await reqCertificationType()
	if (result.code === 200) {
		certificationTypeArr.value = result.data
	}
}
// 发送会员信息
async function postUserAuah() {
	try {
		await reqUserAuah(formData.value)
		ElMessage({
			type: 'success',
			message: "认证成功！"
		})
		// 再次获取用户信息，更新界面
		getUserInfo()
	} catch (error) {
		ElMessage({
			type: "error",
			message: "认证失败！"
		})
	}
}
// 点击提交按钮的回调
async function submitUserAuah() {
	// 进行全部的表单校验
	await form.value.validate()
	// 校验通过则发送会员信息
	postUserAuah()
}
// 超出图片数量时的回调
function exceedHandle() {
	ElMessage({
		type: "error",
		message: "只能上传一张图片！"
	})
}
// 图片上传成功的回调
function successHandle(response: any) {
	// 如果图片上传成功，清除校验结果
	form.value.clearValidate("certificatesUrl")
	// 将图片地址赋值给表单的对应属性
	formData.value.certificatesUrl = response.data
}
// 照片墙预览的钩子
function previewHandle() {
	// 显示对话框
	dialogVisible.value = true
}
// 删除照片的钩子
function removeHandle() {
	// 清空表单里收集的照片数据
	formData.value.certificatesUrl = ""
}
// 重写按钮的回调
function reset() {
	// 清空上传文件
	upload.value.clearFiles()
	// 清空表单里的数据
	formData.value = {
		"certificatesNo": "",
		"certificatesType": "",
		"certificatesUrl": "",
		"name": ""
	}
}


// 挂载后
onMounted(() => {
	// 发送获取用户信息请求
	getUserInfo();
	// 发送获取证件类型请求
	getCertificationType();
})
</script>

<style scoped lang="scss">
.box-card {
	.tip {
		display: flex;
		justify-content: center;
		margin-bottom: 20px;
	}

	.form {
		width: 50%;
		// 左右设为自动即可将在父元素中居中
		margin: 10px auto;
	}
}
</style>